import imp
fm = imp.load_source('fileManager', '.\\fileManager.py')

fileMan = False

rq_blocked = "REQ_BLOCKED"
rq_line    = "REQ_LINE"
upd_line   = "UPD_LINE"
rq_cont    = "REQ_CONT"
upd_text   = "UPD_TEXT"
upd_ping   = "UPD_PING"
save_file  = "SAVE_FILE"
new_line   = "NEW_LINE"
del_line   = "DEL_LINE"
res_vers   = "RES_VERS"
qry_usrs   = "QRY_USRS"

"""
Message types in:
    REQ_BLOCKED F=id                 ->  INF_BLOCKED
    REQ_LINE F=id L=l U=uname        ->  INF_LINE
    UPD_LINE F=id L=l U=uname T=txt  ->  INF_CONT
    REQ_CONT F=id U=uname            ->  INF_CONT
    UPD_TEXT F=id C=uname N=fname    ->  INF_TXT
    UPD_PING F=id C=uname N=fname
    NEW_LINE F=id L=l O=off U=uname  ->  INF_LINE
    DEL_LINE F=id L=l U=uname        ->  INF_LINE
    QRY_USRS F=id                    ->  INF_USRS
    RES_VERS F=id V=v
    SAVE_FILE F=id
    
Message types out:
    INF_BLOCKED F=id L=[list of lines ,-separated]
    INF_LINE F=id L=l U=uid R=t/f
    INF_TXT F=id T={text <p>separated}
    INF_CONT F=id U=uname L=l T={text <p>separated}
    INF_USRS F=id L={uname:line,}
    ERR_NOFILE F=id
    
    TODO
Message types in:
    
Message types out:
"""

def __init__():
    global fileMan
    if fileMan:
        return
    fm.init_manager()
    fileMan = True

def create_inf_cont(fileid, uname):
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    line = f.getUserOcupiedLine(uname)
    
    contents = f.get_contents()
    l = str(line)
    
    response = "INF_CONT F=" + fileid + " U=" + uname + " L="
    response += l + " T={"
    
    for line in contents:
        response += "<p>" + line
    return response + "}"


def getParams(message):
    """Returns a dictionary containing the parameters"""
    msg = message[message.find(" ")+1:]
    params = {}
    for pereche in msg.split():
        x,y,z = pereche.partition("=")
        if y:
            pass
        params[x] = z
    return params


def handle_rq_blocked(params):
    fileid = params["F"]
    f = fm.get_file_info(fileid)
    
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    return "INF_BLOCKED F=" + fileid + " L=" + f.ocupiedLines.keys().__str__()


def handle_rq_line(params):
    fileid = params["F"]
    line = int(params["L"])
    username = params["U"]
    msg = "INF_LINE F=" + fileid + " L=" + params["L"] + " U=" + username + " R="
    
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    if not f.ocupy(line, username):
        msg += "f"
    else:
        msg += "t"
    
    return msg

def handle_upd_line(message):
    req = message.split('=')
    fileid = req[1].split(' ')[0]
    line = int(req[2].split(' ')[0])
    uname = req[3].split(' ')[0]
    text = req[4]
    
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    f.update_line(line, uname, text)
    
    return create_inf_cont(fileid, uname)

def handle_rq_cont(params):
    fileid = params["F"]
    uname = params["U"]
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    return create_inf_cont(fileid, uname)

def handle_upd_text(params):
    fileid = params["F"]
    username = params["C"]
    fname = params["N"]
    fileH = fm.track_new_file(fileid, fname, username)
    
    response = "INF_TXT F=" + fileid + " T={"
    
    for line in fileH.get_contents():
        response += "<p>" + line
    return response + "}"

def handle_upd_ping(params):
    fileid = params["F"]
    username = params["C"]
    fname = params["N"]
    fileH = fm.track_new_file(fileid, fname, username)
    
    fileH.check()
    return "OK"

def handle_save_file(params):
    fileid = params["F"]
    f = fm.get_file_info(fileid)
    
    if f == None:
        return "ERR_NOFILE F=" + fileid
    f.save_contents()
    return "OK"

def handle_new_line(params):
    fileid = params["F"]
    line = int(params["L"])
    username = params["U"]
    offset = int(params["O"])
    f = fm.get_file_info(fileid)
    
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    f.new_line(line, offset, username)
    
    return "INF_LINE F=" + fileid + " L=" + str(line+1) + " U=" + username + " R=t"

def handle_del_line(params):
    fileid = params["F"]
    line = int(params["L"])
    username = params["U"]
    
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    if (f.del_line(line, username)):
        r = 't'
    else:
        r = 'f'
    
    return "INF_LINE F=" + fileid + " L=" + str(line-1) + " U=" + username + " R=" + r

def handle_res_vers(params):
    fileid = params["F"]
    vers = params["V"]
    
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    f.restore_vers(vers)
    
    return "OK"

def handle_qry_usrs(params):
    fileid = params["F"]
    
    f = fm.get_file_info(fileid)
    if f == None:
        return "ERR_NOFILE F=" + fileid
    
    usrList = f.get_usrs()
    
    ret = "INF_USRS F=" + fileid + " L={"
    for user, line in usrList:
        ret += user + ":" + str(line) + ","
    
    ret += "}"
    return ret

def handle_request(message):
    params = getParams(message)
    if message.startswith(rq_blocked):
        return handle_rq_blocked(params)
    elif message.startswith(rq_line):
        return handle_rq_line(params)
    elif message.startswith(upd_line):
        return handle_upd_line(message)
    elif message.startswith(rq_cont):
        return handle_rq_cont(params)
    elif message.startswith(upd_text):
        return handle_upd_text(params)
    elif message.startswith(upd_ping):
        return handle_upd_ping(params)
    elif message.startswith(save_file):
        return handle_save_file(params)
    elif message.startswith(new_line):
        return handle_new_line(params)
    elif message.startswith(del_line):
        return handle_del_line(params) 
    elif message.startswith(res_vers):
        return handle_res_vers(params)
    elif message.startswith(qry_usrs):
        return handle_qry_usrs(params)
    else:
        print "Unkown: " + message
        return "Unkown command"

def web_socket_do_extra_handshake(request):
    __init__()
    pass  # Always accept.

def web_socket_transfer_data(request):
    while True:
        line = request.ws_stream.receive_message()
        #if line is None:
        #    return
        print line
        if isinstance(line, unicode):
            try:
                response = handle_request(line)
            except:
                print "Eroare"
                response = "Error"
                
            request.ws_stream.send_message(response, binary=False)
        else:
            request.ws_stream.send_message(line, binary=True)

# vi:sts=4 sw=4 et
